using System;
using System.IO;
using System.Text;
using System.Text.RegularExpressions;

namespace umlungu.engineX.pop3X {
	/// <summary>
	/// umlungu engineX blog Pop3 class.
	/// </summary>
	public class x_pop3att
	{
		/// <summary>
		/// Local objects and properties
		/// </summary>
		public byte[] _binaryData;

		public string FileExtension {	get {
				string extension = null;
				// if file has a filename and the filename has an extension ...
				if( (_filename != null) &&  Regex.Match(_filename,@"^.*\..*$").Success) {
					// get extension ...
					extension = Regex.Replace(_name,@"^[^\.]*\.([^\.]+)$","$1");
				}
				// NOTE: return null if extension not found ...
				return extension;
			}
		}

		public string FileNoExtension {	get {
				string extension = null;
				// if file has a filename and the filename has an extension ...
				if( (_filename != null) &&  Regex.Match(_filename,@"^.*\..*$").Success) {
					// get extension ...
					extension = Regex.Replace(_name,@"^([^\.]*)\.[^\.]+$","$1");
				}
				// NOTE: return null if extension not found ...
				return extension;
			}
		}
		// FilePath accessor:
		private string _filePath;
		public string FilePath {	get { return _filePath; }}
		// Filename accessor:
		private string _filename;
		public string Filename {	get { return _filename; }}
		// Name accessor:
		private string _name;
		public string Name {	get { return _name; }}
		// Data accessor:
		private string _data;
		public string Data {	get { return _data; }}
		// ContentType accessor:
		private string _contentType;
		public string ContentType {	get { return _contentType; }}
		// ContentTransferEncoding accessor:
		private string _contentTransferEncoding;
		public string ContentTransferEncoding {	get { return _contentTransferEncoding; }}
		// ContentDescription accessor:
		private string _contentDescription;
		public string ContentDescription {	get { return _contentDescription; }}
		// ContentDisposition accessor:
		private string _contentDisposition;
		public string ContentDisposition {	get { return _contentDisposition; }}

		public override string ToString() {
			return 
				"Content-Type: "+_contentType + "\r\n" +
				"Name: "+_name + "\r\n" +
				"Filename: "+_filename+"\r\n"+
				"Content-Transfer-Encoding: "+_contentTransferEncoding+"\r\n"+
				"Content-Description: "+_contentDescription+"\r\n"+
				"Content-Disposition: "+_contentDisposition+"\r\n"+
				"Data :" +_data;
		}

		// FilePath accessor:
		public bool IsBody {	get { return (_contentDisposition==null)?true:false;  }}
		// FilePath accessor:
		public bool IsAttachment {	
			get { 
				bool ret = false;
				if(_contentDisposition != null) {
					ret = Regex.Match(_contentDisposition, "^attachment.*$").Success;
				}
				return ret;
			}
		}

		private void DecodeData() {
			// if this data is an attachment ...
			if( _contentDisposition != null ) {
				// create data folder if it doesn't exist ...
				if(!Directory.Exists(Pop3Statics.DataFolder)) {
					Directory.CreateDirectory(Pop3Statics.DataFolder);
				}

				_filePath = Pop3Statics.DataFolder + @"\" + _filename;

				// if BASE-64 data ...
				if( (_contentDisposition.Equals("attachment;")) && (_contentTransferEncoding.ToUpper().Equals("BASE64")) ) {
					// convert attachment from BASE64 ...
					_binaryData = Convert.FromBase64String(_data.Replace("\n",""));
					BinaryWriter bw = new BinaryWriter(new FileStream(_filePath,FileMode.Create) );
					bw.Write(_binaryData);
					bw.Flush();
					bw.Close();
				}
				else
				// if PRINTABLE ...
				if( (_contentDisposition.Equals("attachment;")) && (_contentTransferEncoding.ToUpper().Equals("QUOTED-PRINTABLE")) ) {
					using(StreamWriter sw = File.CreateText(_filePath) ) {
						sw.Write(Pop3Statics.FromQuotedPrintable(_data));
						sw.Flush();
						sw.Close();
					}
				}
			}
		}

		public x_pop3att(string contentType, string data) {
			_contentType = contentType;
			_data = data;
		}

		public x_pop3att(string contentType, string name, string filename, string contentTransferEncoding, string contentDescription, string contentDisposition, string data) {
			_contentType = contentType;
			_name = name;
			_filename = filename;
			_contentTransferEncoding = contentTransferEncoding;
			_contentDescription = contentDescription;
			_contentDisposition = contentDisposition;
			_data = data;

			DecodeData();
		}
	}
	
	
	/// <summary>
	/// umlungu engineX blog Pop3 class.
	/// </summary>
	public class Pop3Statics
	{
		public const string DataFolder = @"c:\POP3Temp";

		public static string FromQuotedPrintable(string inString) {
			string outputString = null;
			string inputString = inString.Replace("=\n","");

			if(inputString.Length > 3) {
				// initialise output string ...
				outputString = "";

				for(int x=0; x<inputString.Length;) { 
					string s1 = inputString.Substring(x,1);

					if( (s1.Equals("=")) && ((x+2) < inputString.Length) ) {
						string hexString = inputString.Substring(x+1,2);

						// if hexadecimal ...
						if( Regex.Match(hexString.ToUpper() ,@"^[A-F|0-9]+[A-F|0-9]+$").Success ) {
							// convert to string representation ...
							outputString +=  System.Text.Encoding.ASCII.GetString(new byte[] {System.Convert.ToByte(hexString,16)} );
							x+= 3;
						} else {
							outputString += s1;
							++x;
						}
					} else {
						outputString += s1;
						++x;
					}
				}
			}
			else {
				outputString = inputString;
			}

			return outputString.Replace("\n","\r\n");
		}
	}
}
